<?php


namespace App\Http\Controllers;


use App\Internals\StudyInternal;
use App\Models\Order;
use App\Models\OrderItem;
use EasyWeChat\Factory;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Events\OrderSuccessEvent;

class PaymentController extends Controller
{
    /*
     * @api post /billing-api/payment/notify 微信支付回调
     * @version 0.0.1
     * @group web
     *
     * @param body int [quantity] 数量
     *
     * @response 200 正常结果 {
     *  "code":0,
     *  "msg":"",
     *  "data":{}
     * }
     */
    public function notify()
    {
        Log::info('============== wxpay notify start ===============');
        $config = config('wechat.payment');
        $app = Factory::payment($config);
        $app['cache'] = app('easyWechatCache');
        $response = $app->handlePaidNotify(function ($message, $fail) use ($app) {
            Log::info('message: ' . var_export($message, true));
            // 使用通知"商户订单号"找到订单
            /** @var Order $orderObj */
            $orderObj = Order::where('trade_no', $message['out_trade_no'])->first();
            // 如果订单不存在 或者 订单已经支付过了
            if (!$orderObj || $orderObj->getPaidAt()) {
                // 告诉微信，我已经处理完了，订单没找到，别再通知我了
                return true;
            }
            // return_code 表示通信状态，不代表支付状态
            if ($message['return_code'] === 'SUCCESS') {
                try {
                    DB::beginTransaction();
                    // 用户是否支付成功
                    if (array_get($message, 'result_code') === 'SUCCESS') {
                        // 在这里调用微信的【订单查询】接口查一下该笔订单的情况，确认是已经支付，防止假通知
                        $queryOrderInfo = $app->order->queryByTransactionId($message['transaction_id']);
                        if (array_get($queryOrderInfo, 'result_code') === 'SUCCESS' && $queryOrderInfo['trade_state'] === 'SUCCESS') {
                            // 判断支付金额是否一致
                            $totalFee = bcdiv($message['total_fee'], 100, 2);
                            if ($totalFee == $orderObj->getActualAmount()) {
                                $orderObj->setPaidAmount($totalFee);
                                $orderObj->setPaidAt($this->nowTimestamp()); // 更新支付时间为当前时间
                                $orderObj->setStatus(Order::ORDER_STATUS['paid']);
                                $orderObj->setWxTransactionId($message['transaction_id']);
                                // 更新订单项目
                                OrderItem::where('order_id', $orderObj->getId())->update(['status'=>Order::ORDER_STATUS['paid']]);
                                // 生成课程
                                $courses = $orderObj->items()->orderBy('level', 'asc')->get(['course_id as courseId', 'level'])->toArray();
                                StudyInternal::createCourse($orderObj->getUserId(), $orderObj->getId(), $courses);
                                Log::info('OrderSuccessEvent start');
                                try {
                                    event(new OrderSuccessEvent($orderObj, $courses));
                                } catch(\Exception $e) {
                                    Log::info('OrderSuccessEvent failed: '.$e->getMessage());
                                }
                                Log::info('OrderSuccessEvent end');
                            }
                        }
                    } elseif (array_get($message, 'result_code') === 'FAIL') {
                        // 用户支付失败
                        $orderObj->setStatus(Order::ORDER_STATUS['fail']);
                    }
                    $orderObj->save();
                    // 生成学习的课程
                    DB::commit();
                    return true;
                } catch (\Exception $e) {
                    DB::rollBack();
                    return $fail('通信失败，请稍后再通知我');
                }
            } else {
                return $fail('通信失败，请稍后再通知我');
            }
        });
        return $response;
    }
}
